import axios, { AxiosError, InternalAxiosRequestConfig } from 'axios';
import qs from 'qs';
import router from '@/router';
import { message } from 'ant-design-vue';
import { API_CONFIG, isOriginAllowed } from './config';

const env = import.meta.env.DEV;
const defaultContentType = 'application/x-www-form-urlencoded; charset=UTF-8';
// 添加客户端ID
const clientId = 'e5cd7e4891bf95d1d19206ce24a7b32e';

const service = axios.create({
	baseURL: API_CONFIG.API_BASE_URL, // API基础URL
	timeout: 50000, // 请求超时时间
	withCredentials: true, // 跨域携带cookie
	validateStatus: (status: number) => {
		return status >= 200 && status <= 500;
	},
	headers: {
		'Content-Type': 'application/json;charset=UTF-8'
	}
});

const getToken = function (): string {
	return window.localStorage.getItem('token') || '';
};

/**
 * @description 处理开发环境和生产环境接口url
 * @param config Axios请求配置
 * @returns 返回格式化后的URL
 */
const formatUrl = (config: InternalAxiosRequestConfig<any>): string | undefined => {
	if (!config.url) return;

	// 如果URL已经包含完整的前缀，则直接返回
	if (
		config.url.startsWith(API_CONFIG.DEV_PREFIX) ||
		config.url.startsWith(API_CONFIG.PROD_PREFIX)
	) {
		return config.url;
	}

	// 根据环境添加不同的前缀
	const prefix = env ? API_CONFIG.DEV_PREFIX : API_CONFIG.PROD_PREFIX;
	
	// 确保URL正确拼接
	const formattedUrl = config.url.startsWith('/') 
		? `${prefix}${config.url}` 
		: `${prefix}/${config.url}`;
		
	return formattedUrl;
};

/**
 * request拦截器 axios
 * config是axios.post或者get第三个参数的config配置。
 * post和get第一，二个参数实际上是第三个的子集。
 * config可以包含所有axios可用参数，和本系统扩展参数例如：baseUrl
 */
service.interceptors.request.use(
	config => {
		config.url = formatUrl(config);
		
		// 检查内容类型是否为表单，如果是则进行转换
		if (config.headers['Content-Type'] === defaultContentType || 
		    config.headers['content-type'] === defaultContentType) {
			config.data = qs.stringify(config.data);
		}
		
		// 添加统一请求头
		config.headers['content-language'] = 'zh_CN';
		config.headers['clientId'] = clientId;
		config.headers['Accept'] = 'application/json, text/plain, */*';
		
		// 处理CORS配置
		if (API_CONFIG.CORS_ENABLED) {
			const origin = window.location.origin;
			config.headers['Origin'] = origin;
			
			// 只有当请求源在允许列表中时才添加CORS头
			if (isOriginAllowed(origin)) {
				config.headers['Access-Control-Allow-Origin'] = '*'; // 或使用具体的origin
				config.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS';
				config.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization';
				config.headers['X-Requested-With'] = 'XMLHttpRequest';
			}
		}
		
		// 检查是否需要加密
		const needEncrypt = config.headers['isEncrypt'];
		if (needEncrypt) {
			// 确保传递了加密标记和密钥
			if (!config.headers['encryptKey']) {
				console.warn('需要加密但未提供加密密钥');
			}
		}
		
		// 检查是否需要token
		const isToken = config.headers.isToken !== false;
		if (isToken) {
			// 有token则加token
			if (getToken()) {
				config.headers.Authorization = 'Bearer ' + getToken();
			}
		}
		
		return config;
	},
	(error: AxiosError) => Promise.reject(error)
);

/**
 * respone拦截器 axios
 * 处理401（未授权），重定向到登录页面
 * 处理文件流响应
 * 处理错误码和错误信息
 */
service.interceptors.response.use(
	response => {
		const { data } = response;
		const dataMessage = data.msg || data.error_description || '未知错误';
		const headersType = response.headers['Content-Type'] || response.headers['content-type'];
		const contentType: unknown[] = ['application/vnd.ms-excel;charset=utf-8', 'application/octet-stream'];
		// 文件流数据直接返回
		if (headersType && contentType.includes(headersType)) {
			return response;
		}

		// 处理401（未授权），重定向到登录页面
		if (data.code === 401) {
			router.replace({ path: '/login' });
			return Promise.reject(data);
		}

		// 处理自定义错误码
		if (data.hasOwnProperty('error_code')) {
			message.error(dataMessage);
			return Promise.reject(data);
		}

		// 处理业务错误
		if (data.code !== 200) {
			return Promise.reject(data);
		}
		
		// 正常返回数据
		return data;
	},
	(error: AxiosError) => {
		// 处理CORS错误
		if (error.message && error.message.includes('Network Error')) {
			if (API_CONFIG.CORS_ENABLED) {
				const origin = window.location.origin;
				if (!isOriginAllowed(origin)) {
					message.error(`跨域请求被拒绝：${origin} 不在允许的源列表中。请联系管理员更新CORS配置。`);
				} else {
					message.error('网络错误，可能是跨域问题导致。请确保后端已开启CORS支持。');
				}
			} else {
				message.error('网络错误，可能是跨域问题导致。CORS支持未启用，请在config.ts中启用CORS_ENABLED。');
			}
			console.error('CORS错误详情:', error);
		}
		return Promise.reject(error);
	}
);

export default service;
